package job

import (
	"cron-go/configs"
	"cron-go/internal/pkg/crontab/dao"
	"cron-go/internal/pkg/crontab/enum"
	"cron-go/internal/pkg/crontab/models"
	"cron-go/internal/pkg/crontab/task"
	"cron-go/internal/pkg/crontab/worker"
	"fmt"
	"time"

	"github.com/go-liam/util/conv"
	"github.com/go-liam/util/response"
)

func RunJob() {
	go InitTaskJob()
	go WorkerJob()
}

func WorkerJob() {
	t := conv.RandomNumber(3000, 4000)
	time.Sleep(time.Duration(t) * time.Millisecond)
	println("[INFO] Run WorkerJob")
	task.ServiceCron.RemoveJob("ClearWorkerJob")
	task.ServiceCron.RemoveJob("ReadyWorkerJob")
	task.ServiceCron.RemoveJob("FinishJob")
	task.AddFunc(configs.Cron.ClearSpec, worker.ClearWorker, "ClearWorkerJob") //At 04:10.
	//task.AddFunc("1/5 * * * * *", ClearWorker, "ClearWorkerJob") // every 5 second
	task.AddFunc(configs.Cron.ReadySpec, ReadyJob, "ReadyWorkerJob") //At every 30 second
	task.AddFunc(configs.Cron.FinishSpec, FinishJob, "FinishJob")    //At every 40 second
}

func InitTaskJob() int {
	t := conv.RandomNumber(1000, 2000)
	time.Sleep(time.Duration(t) * time.Millisecond)
	println("[INFO] Run InitTaskJob")
	r := &response.ListParameter{WhereSt: " and `status` =1 ", OrderSt: " "}
	ls, _ := new(dao.TaskDao).FindAll(r)
	//bind
	baseModels := make([]*models.TaskMysqlModel, 0)
	baseModels = append(baseModels, ls...)
	task.Service.BatchAdd(baseModels)
	return len(baseModels)
}

func ReadyJob() {
	ti := time.Now().Unix() - 2 //处理1秒以后的
	where := fmt.Sprintf(" and `updated_at` < %v ", ti)
	r := &response.ListParameter{WhereSt: where, OrderSt: ""}
	ls, _ := dao.ReadyDaoServer.FindAll(r)
	deleIds := make([]int64, 0)
	sendIds := make([]int64, 0)
	//TODO 缓存 TaskList
	for _, i := range ls {
		// 超时的
		if (ti - i.UpdatedAt) > (60 * 5) {
			deleIds = append(deleIds, i.ID)
			go worker.NotifyWorkByID(i.TaskID, enum.DoStatusFail)
		} else if i.WorkerStatus == 0 { // 分派任务
			go worker.WorkByID(i.TaskID)
			sendIds = append(sendIds, i.TaskID)
			deleIds = append(deleIds, i.ID)
		}
	}
	if len(deleIds) > 0 {
		dao.ReadyDaoServer.Delete(deleIds)
	}
	if len(sendIds) > 0 {
		dao.TaskDaoServer.UpdateDoStatus(sendIds, enum.DoStatusNew)
	}
}

func FinishJob() {
	ti := time.Now().Unix() - 2 //处理2秒以后的
	where := fmt.Sprintf(" and `updated_at` < %v ", ti)
	r := &response.ListParameter{WhereSt: where, OrderSt: ""}
	ls, _ := dao.FinishDaoServer.FindAll(r)
	deleIds := make([]int64, 0)
	sendIds := make([]int64, 0)
	//TODO 缓存 TaskList
	for _, i := range ls {
		// 超时的,积压的
		if (ti - i.UpdatedAt) > (60 * 5) {
			println("[INFO] FinishJob outTime ")
			deleIds = append(deleIds, i.ID)
		} else if i.Status == 0 { // 分派任务
			println("[INFO] FinishJob send work ")
			sendIds = append(sendIds, i.TaskID)
			deleIds = append(deleIds, i.ID)
			go worker.NotifyWorkByID(i.TaskID, i.WorkerStatus)
		}
	}
	if len(deleIds) > 0 {
		dao.FinishDaoServer.Delete(deleIds)
	}
	if len(sendIds) > 0 {
		dao.TaskDaoServer.UpdateNotifyStatus(sendIds, 1)
	}
}

func UpdateTaskJobInfo() {

}
